home *** CD-ROM | disk | FTP | other *** search
/ Inter.Net 55-1 / Inter.Net 55-1.iso / CBuilder / Setup / BCB / data.z / complex.h < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-09  |  43.8 KB  |  1,540 lines

  1. #ifndef __STD_COMPLEX
  2. #define __STD_COMPLEX
  3. #pragma option push -b -a4 -Vx- -Ve- -w-inl -w-aus -w-sig
  4.  
  5. /***************************************************************************
  6.  *
  7.  * complex - Declaration for the Standard Library complex class
  8.  *
  9.  * $Id: complex,v 1.99 1996/09/27 07:49:07 smithey Exp $
  10.  *
  11.  ***************************************************************************
  12.  *
  13.  * (c) Copyright 1994, 1995 Rogue Wave Software, Inc.
  14.  * ALL RIGHTS RESERVED *
  15.  * The software and information contained herein are proprietary to, and
  16.  * comprise valuable trade secrets of, Rogue Wave Software, Inc., which
  17.  * intends to preserve as trade secrets such software and information.
  18.  * This software is furnished pursuant to a written license agreement and
  19.  * may be used, copied, transmitted, and stored only in accordance with
  20.  * the terms of such license and with the inclusion of the above copyright
  21.  * notice.  This software and information or any other copies thereof may
  22.  * not be provided or otherwise made available to any other person.
  23.  *
  24.  * Notwithstanding any other lease or license that may pertain to, or
  25.  * accompany the delivery of, this computer software and information, the
  26.  * rights of the Government regarding its use, reproduction and disclosure
  27.  * are as set forth in Section 52.227-19 of the FARS Computer
  28.  * Software-Restricted Rights clause.
  29.  * 
  30.  * Use, duplication, or disclosure by the Government is subject to
  31.  * restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
  32.  * Technical Data and Computer Software clause at DFARS 252.227-7013.
  33.  * Contractor/Manufacturer is Rogue Wave Software, Inc.,
  34.  * P.O. Box 2328, Corvallis, Oregon 97339.
  35.  *
  36.  * This computer software and information is distributed with "restricted
  37.  * rights."  Use, duplication or disclosure is subject to restrictions as
  38.  * set forth in NASA FAR SUP 18-52.227-79 (April 1985) "Commercial
  39.  * Computer Software-Restricted Rights (April 1985)."  If the Clause at
  40.  * 18-52.227-74 "Rights in Data General" is specified in the contract,
  41.  * then the "Alternate III" clause applies.
  42.  *
  43.  **************************************************************************/
  44.  
  45. #include <stdcomp.h>
  46. #include <rw/stddefs.h>
  47. #include <rw/math.h>
  48.  
  49. #ifndef _RWSTD_HEADER_REQUIRES_HPP
  50. #include <utility>
  51. #else
  52. #include <utility.hpp>
  53. #endif
  54.  
  55. #ifndef _RW_STD_IOSTREAM
  56. #include <iostream.h>
  57. #else
  58. #include <iostream>
  59. #endif
  60.  
  61. #ifndef _RWSTD_NO_NAMESPACE 
  62. namespace std {
  63. #endif
  64.  
  65. #ifdef _RWSTD_NO_FORWARD_SPECIALIZATIONS
  66. template <class T>
  67. class _RWSTDExportTemplate complex
  68. {
  69.   public:
  70.     typedef T value_type;
  71.  
  72.     complex (const T& re_arg=0, const T& imag_arg=0) { re_=re_arg; im_=imag_arg; } 
  73.     ~complex() { ; }
  74.  
  75.     T imag () const { return im_; }
  76.     T real () const { return re_; }
  77.  
  78. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  79.     template <class X> complex (const complex<X>& rhs) {re_=rhs.real(); im_=rhs.imag();}
  80.  
  81.     template <class X> complex<T>& operator=  (const complex<X>& rhs) {re_=rhs.real(); im_=rhs.imag(); return *this;}
  82.     template <class X> complex<T>& operator+= (const complex<X>& rhs) {re_+=rhs.real(); im_+=rhs.imag(); return *this;}
  83.     template <class X> complex<T>& operator-= (const complex<X>& rhs) {re_-=rhs.real(); im_-=rhs.imag(); return *this;}
  84.     template <class X> complex<T>& operator*= (const complex<X>& rhs) {T tmp=re_*rhs.real()-im_*rhs.imag(); im_=im_*rhs.real()+re_*rhs.imag(); re_=tmp; return *this;}
  85.     template <class X> complex<T>& operator/= (const complex<X>&); 
  86. #endif
  87.     
  88.     complex<T>& operator=  (T); 
  89.     complex<T>& operator+= (T); 
  90.     complex<T>& operator-= (T); 
  91.     complex<T>& operator*= (T); 
  92.     complex<T>& operator/= (T); 
  93.  
  94.   private:
  95.     T re_, im_;
  96. };
  97.  
  98.  
  99. #else
  100.  
  101. //
  102. // The complex template definition must be placed after specializations to 
  103. // satisfy several compilers' rather bizarre preference.
  104. //
  105. template <class T>
  106. class _RWSTDExportTemplate complex;
  107. #endif
  108.  
  109. #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS 
  110. _RWSTD_TEMPLATE class _RWSTDExport complex<float>;
  111. _RWSTD_TEMPLATE class _RWSTDExport complex<double>;
  112. #ifndef _RWSTD_NO_LONGDOUBLE
  113. _RWSTD_TEMPLATE class _RWSTDExport complex<long double>;
  114. #endif
  115. #endif
  116.  
  117. _RWSTD_TEMPLATE
  118. class _RWSTDExport complex<float>
  119. {
  120.   public:
  121.     typedef float value_type;
  122.  
  123.     complex (const float& re_arg=0.0f, const float& imag_arg=0.0f) { re_=re_arg; im_=imag_arg; }
  124.     complex (const complex<float>&);
  125.     #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS
  126.     _EXPLICIT complex (const complex<double>&); 
  127.     #ifndef _RWSTD_NO_LONGDOUBLE
  128.     _EXPLICIT complex (const complex<long double>&);
  129.     #endif
  130.     #endif 
  131.     ~complex() { ; }
  132.  
  133.     float imag () const { return im_; }
  134.     float real () const { return re_; }
  135.  
  136. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  137.     template <class X> complex<float>& operator=  (const complex<X>& rhs) {re_=rhs.real(); im_=rhs.imag(); return *this;}
  138.     template <class X> complex<float>& operator+= (const complex<X>& rhs) {re_+=rhs.real(); im_+=rhs.imag(); return *this;}
  139.     template <class X> complex<float>& operator-= (const complex<X>& rhs) {re_-=rhs.real(); im_-=rhs.imag(); return *this;}
  140.     template <class X> complex<float>& operator*= (const complex<X>& rhs) {float tmp=re_*rhs.real()-im_*rhs.imag(); im_=im_*rhs.real()+re_*rhs.imag(); re_=tmp; return *this;}
  141.     template <class X> complex<float>& operator/= (const complex<X>&); 
  142. #else /* Have to specialize each one :-( */
  143.  
  144.     complex<float>& operator=  (const complex<float>&); 
  145.     complex<float>& operator+= (const complex<float>&); 
  146.     complex<float>& operator-= (const complex<float>&); 
  147.     complex<float>& operator*= (const complex<float>&); 
  148.     complex<float>& operator/= (const complex<float>&); 
  149.  
  150.     #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS
  151.     complex<float>& operator=  (const complex<double>&); 
  152.     complex<float>& operator+= (const complex<double>&); 
  153.     complex<float>& operator-= (const complex<double>&); 
  154.     complex<float>& operator*= (const complex<double>&); 
  155.     complex<float>& operator/= (const complex<double>&); 
  156.  
  157.     #ifndef _RWSTD_NO_LONGDOUBLE
  158.     complex<float>& operator=  (const complex<long double>&); 
  159.     complex<float>& operator+= (const complex<long double>&); 
  160.     complex<float>& operator-= (const complex<long double>&); 
  161.     complex<float>& operator*= (const complex<long double>&); 
  162.     complex<float>& operator/= (const complex<long double>&);
  163.     #endif
  164.     #endif  
  165. #endif
  166.  
  167.     complex<float>& operator=  (float); 
  168.     complex<float>& operator+= (float); 
  169.     complex<float>& operator-= (float); 
  170.     complex<float>& operator*= (float); 
  171.     complex<float>& operator/= (float); 
  172.  
  173.   private:
  174.     float re_, im_;
  175. };
  176.  
  177. _RWSTD_TEMPLATE
  178. class  _RWSTDExport complex<double>
  179. {
  180.   public:
  181.     typedef double value_type;
  182.  
  183.     complex (const double& re_arg=0.0, const double& imag_arg=0.0) { re_=re_arg; im_=imag_arg; } 
  184.     complex (const complex<float>&); 
  185.     complex (const complex<double>&);
  186.     #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS
  187.     #ifndef _RWSTD_NO_LONGDOUBLE  
  188.     _EXPLICIT complex (const complex<long double>&); 
  189.     #endif
  190.     #endif
  191.     ~complex() { ; }
  192.  
  193.     double imag () const { return im_; }
  194.     double real () const { return re_; }
  195.  
  196. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  197.     template <class X> complex<double>& operator=  (const complex<X>& rhs) {re_=rhs.real(); im_=rhs.imag(); return *this;}
  198.     template <class X> complex<double>& operator+= (const complex<X>& rhs) {re_+=rhs.real(); im_+=rhs.imag(); return *this;}
  199.     template <class X> complex<double>& operator-= (const complex<X>& rhs) {re_-=rhs.real(); im_-=rhs.imag(); return *this;}
  200.     template <class X> complex<double>& operator*= (const complex<X>& rhs) {double tmp=re_*rhs.real()-im_*rhs.imag(); im_=im_*rhs.real()+re_*rhs.imag(); re_=tmp; return *this;}
  201.     template <class X> complex<double>& operator/= (const complex<X>&);
  202.  
  203. #else /* Have to specialize each one :-( */
  204.  
  205.     complex<double>& operator=  (const complex<float>&); 
  206.     complex<double>& operator+= (const complex<float>&); 
  207.     complex<double>& operator-= (const complex<float>&);
  208.     complex<double>& operator*= (const complex<float>& rhs); 
  209.     complex<double>& operator/= (const complex<float>&); 
  210.  
  211.     complex<double>& operator=  (const complex<double>& rhs); 
  212.     complex<double>& operator+= (const complex<double>& rhs); 
  213.     complex<double>& operator-= (const complex<double>& rhs); 
  214.     complex<double>& operator*= (const complex<double>& rhs); 
  215.     complex<double>& operator/= (const complex<double>&); 
  216.  
  217.     #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS
  218.     #ifndef _RWSTD_NO_LONGDOUBLE  
  219.     complex<double>& operator=  (const complex<long double>&); 
  220.     complex<double>& operator+= (const complex<long double>&); 
  221.     complex<double>& operator-= (const complex<long double>&); 
  222.     complex<double>& operator*= (const complex<long double>&); 
  223.     complex<double>& operator/= (const complex<long double>&);
  224.     #endif
  225.     #endif 
  226. #endif
  227.  
  228.     complex<double>& operator=  (double); 
  229.     complex<double>& operator+= (double); 
  230.     complex<double>& operator-= (double); 
  231.     complex<double>& operator*= (double); 
  232.     complex<double>& operator/= (double); 
  233.  
  234.  
  235.   private:
  236.     double re_, im_;
  237. };
  238.  
  239. #ifndef _RWSTD_NO_LONGDOUBLE  
  240.  
  241. _RWSTD_TEMPLATE
  242. class _RWSTDExport complex<long double>
  243. {
  244.   public:
  245.     typedef long double value_type;
  246.  
  247.     complex (const long double& re_arg=0.0L, const long double& imag_arg=0.0L) { re_=re_arg; im_=imag_arg; } 
  248.     complex (const complex<float>&);
  249.     complex (const complex<double>&);
  250.     complex (const complex<long double>&);
  251.     ~complex() { ; }
  252.  
  253.     long double imag () const { return im_; }
  254.     long double real () const { return re_; }
  255.  
  256. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  257.     template <class X> complex<long double>& operator=  (const complex<X>& rhs) {re_=rhs.real(); im_=rhs.imag(); return *this;}
  258.     template <class X> complex<long double>& operator+= (const complex<X>& rhs) {re_+=rhs.real(); im_+=rhs.imag(); return *this;}
  259.     template <class X> complex<long double>& operator-= (const complex<X>& rhs) {re_-=rhs.real(); im_-=rhs.imag(); return *this;}
  260.     template <class X> complex<long double>& operator*= (const complex<X>& rhs) {long double tmp=re_*rhs.real()-im_*rhs.imag(); im_=im_*rhs.real()+re_*rhs.imag(); re_=tmp; return *this;}
  261.     template <class X> complex<long double>& operator/= (const complex<X>&); 
  262.  
  263. #else /* Have to specialize each one :-( */
  264.  
  265.     complex<long double>& operator=  (const complex<float>&); 
  266.     complex<long double>& operator+= (const complex<float>&); 
  267.     complex<long double>& operator-= (const complex<float>&); 
  268.     complex<long double>& operator*= (const complex<float>&); 
  269.     complex<long double>& operator/= (const complex<float>&); 
  270.  
  271.     complex<long double>& operator=  (const complex<double>&); 
  272.     complex<long double>& operator+= (const complex<double>&); 
  273.     complex<long double>& operator-= (const complex<double>&); 
  274.     complex<long double>& operator*= (const complex<double>&); 
  275.     complex<long double>& operator/= (const complex<double>&); 
  276.  
  277.     complex<long double>& operator=  (const complex<long double>&); 
  278.     complex<long double>& operator+= (const complex<long double>&); 
  279.     complex<long double>& operator-= (const complex<long double>&); 
  280.     complex<long double>& operator*= (const complex<long double>&); 
  281.     complex<long double>& operator/= (const complex<long double>&); 
  282. #endif
  283.  
  284.     complex<long double>& operator=  (long double); 
  285.     complex<long double>& operator+= (long double); 
  286.     complex<long double>& operator-= (long double); 
  287.     complex<long double>& operator*= (long double); 
  288.     complex<long double>& operator/= (long double); 
  289.  
  290.  
  291.   private:
  292.     long double re_, im_;
  293. };
  294. #endif
  295.  
  296. #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS
  297. template <class T>
  298. class _RWSTDExportTemplate complex
  299. {
  300.   public:
  301.     typedef T value_type;
  302.  
  303.     complex (const T& re_arg=0, const T& imag_arg=0) { re_=re_arg; im_=imag_arg; } 
  304.     ~complex() { ; }
  305.  
  306.     T imag () const { return im_; }
  307.     T real () const { return re_; }
  308.  
  309. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  310.     template <class X> complex (const complex<X>& rhs) {re_=rhs.real(); im_=rhs.imag();}
  311.  
  312.     template <class X> complex<T>& operator=  (const complex<X>& rhs) {re_=rhs.real(); im_=rhs.imag(); return *this;}
  313.     template <class X> complex<T>& operator+= (const complex<X>& rhs) {re_+=rhs.real(); im_+=rhs.imag(); return *this;}
  314.     template <class X> complex<T>& operator-= (const complex<X>& rhs) {re_-=rhs.real(); im_-=rhs.imag(); return *this;}
  315.     template <class X> complex<T>& operator*= (const complex<X>& rhs) {T tmp=re_*rhs.real()-im_*rhs.imag(); im_=im_*rhs.real()+re_*rhs.imag(); re_=tmp; return *this;}
  316.     template <class X> complex<T>& operator/= (const complex<X>&); 
  317. #endif
  318.     
  319.     complex<T>& operator=  (T); 
  320.     complex<T>& operator+= (T); 
  321.     complex<T>& operator-= (T); 
  322.     complex<T>& operator*= (T); 
  323.     complex<T>& operator/= (T); 
  324.  
  325.   private:
  326.     T re_, im_;
  327. };
  328. #endif
  329.  
  330. //
  331. // Temporarily turn off the warnings under the Borland compiler that
  332. // say 'Functions containing ... cannot be inlined'
  333. //
  334. #if defined(__BORLANDC__)
  335. #pragma option -w-inl
  336. #endif
  337.  
  338. template <class T>
  339. inline complex<T>&
  340. complex<T>::operator= (T rhs) 
  341. {
  342.     re_ = rhs; im_ = 0.0; return *this;
  343. }
  344.  
  345. template <class T>
  346. inline complex<T>&
  347. complex<T>::operator+= (T rhs) 
  348. {
  349.     re_ += rhs; return *this;
  350. }
  351.  
  352. template <class T>
  353. inline complex<T>&
  354. complex<T>::operator-= (T rhs) 
  355. {
  356.     re_ -= rhs;  return *this;
  357. }
  358.  
  359. template <class T>
  360. inline complex<T>&
  361. complex<T>::operator*= (T rhs) 
  362. {    
  363.     T tmp = re_*rhs; 
  364.     im_       = im_*rhs; 
  365.     re_       = tmp;
  366.     return *this;
  367. }
  368.  
  369. template <class T>
  370. inline complex<T>& 
  371. complex<T>::operator/= (T rhs)  
  372. {
  373.     T denom = rhs*rhs;
  374.     T re    = (re_*rhs)/denom;
  375.     T im    = (rhs*im_)/denom;
  376.     re_               = re;
  377.     im_               = im;
  378.     return *this;
  379. }
  380.  
  381.  
  382. //
  383. // complex<float> specializations.
  384. //
  385. inline
  386. complex<float>::complex (const complex<float>& cf)
  387. {
  388.     re_ = cf.real(); im_ = cf.imag();
  389. }
  390.  
  391. #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS 
  392. inline
  393. complex<float>::complex (const complex<double>& cd)
  394. {
  395.     re_ = _RWSTD_STATIC_CAST(float,cd.real()); 
  396.     im_ = _RWSTD_STATIC_CAST(float,cd.imag());
  397. }
  398.  
  399. #ifndef _RWSTD_NO_LONGDOUBLE
  400. inline
  401. complex<float>::complex (const complex<long double>& cld)
  402. {
  403.     re_ = _RWSTD_STATIC_CAST(float,cld.real()); 
  404.     im_ = _RWSTD_STATIC_CAST(float,cld.imag());
  405. }
  406. #endif
  407. #endif
  408.  
  409. inline complex<float>&
  410. complex<float>::operator= (float rhs) 
  411. {
  412.     re_ = rhs; im_ = 0.0; return *this;
  413. }
  414.  
  415. inline complex<float>&
  416. complex<float>::operator+= (float rhs) 
  417. {
  418.     re_ += rhs; return *this;
  419. }
  420.  
  421. inline complex<float>&
  422. complex<float>::operator-= (float rhs) 
  423. {
  424.     re_ -= rhs;  return *this;
  425. }
  426.  
  427. inline complex<float>&
  428. complex<float>::operator*= (float rhs) 
  429. {    
  430.     float tmp = re_*rhs; 
  431.     im_       = im_*rhs; 
  432.     re_       = tmp;
  433.     return *this;
  434. }
  435.  
  436.  
  437. #ifdef _RWSTD_NO_MEMBER_TEMPLATES 
  438. inline complex<float>&
  439. complex<float>::operator= (const complex<float>& rhs) 
  440. {
  441.     re_ = rhs.real(); im_ = rhs.imag(); return *this;
  442. }
  443.  
  444. inline complex<float>&
  445. complex<float>::operator+= (const complex<float>& rhs) 
  446. {
  447.     re_ += rhs.real(); im_ += rhs.imag(); return *this;
  448. }
  449.  
  450. inline complex<float>&
  451. complex<float>::operator-= (const complex<float>& rhs) 
  452. {
  453.     re_ -= rhs.real(); im_ -= rhs.imag(); return *this;
  454. }
  455.  
  456. inline complex<float>&
  457. complex<float>::operator*= (const complex<float>& rhs) 
  458. {    
  459.     float tmp = re_*rhs.real()-im_*rhs.imag(); 
  460.     im_       = im_*rhs.real()+re_*rhs.imag(); 
  461.     re_       = tmp;
  462.     return *this;
  463. }
  464.  
  465. #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS 
  466. inline complex<float>&
  467. complex<float>::operator= (const complex<double>& rhs) 
  468. {
  469.     re_ = _RWSTD_STATIC_CAST(float,rhs.real()); 
  470.     im_ = _RWSTD_STATIC_CAST(float,rhs.imag()); 
  471.     return *this;
  472. }
  473.  
  474. inline complex<float>&
  475. complex<float>::operator+= (const complex<double>& rhs) 
  476. {
  477.     re_ += _RWSTD_STATIC_CAST(float,rhs.real()); 
  478.     im_ += _RWSTD_STATIC_CAST(float,rhs.imag()); 
  479.     return *this;
  480. }
  481.  
  482. inline complex<float>&
  483. complex<float>::operator-= (const complex<double>& rhs) 
  484. {    
  485.     re_ -= _RWSTD_STATIC_CAST(float,rhs.real()); 
  486.     im_ -= _RWSTD_STATIC_CAST(float,rhs.imag()); 
  487.     return *this;
  488. }
  489.  
  490. inline complex<float>&
  491. complex<float>::operator*= (const complex<double>& rhs) 
  492. {    
  493.     float tmp = re_*_RWSTD_STATIC_CAST(float,rhs.real())-
  494.                 im_*_RWSTD_STATIC_CAST(float,rhs.imag()); 
  495.     im_       = im_*_RWSTD_STATIC_CAST(float,rhs.real())+
  496.                 re_*_RWSTD_STATIC_CAST(float,rhs.imag()); 
  497.     re_       = tmp;
  498.     return *this;
  499. }
  500.  
  501. #ifndef _RWSTD_NO_LONGDOUBLE
  502. inline complex<float>&
  503. complex<float>::operator= (const complex<long double>& rhs) 
  504. {    
  505.     re_ = _RWSTD_STATIC_CAST(float,rhs.real()); 
  506.     im_ = _RWSTD_STATIC_CAST(float,rhs.imag()); 
  507.     return *this;
  508. }
  509.  
  510. inline complex<float>&
  511. complex<float>::operator+= (const complex<long double>& rhs) 
  512. {    
  513.     re_ += _RWSTD_STATIC_CAST(float,rhs.real()); 
  514.     im_ += _RWSTD_STATIC_CAST(float,rhs.imag()); 
  515.     return *this;
  516. }
  517.  
  518. inline complex<float>&
  519. complex<float>::operator-= (const complex<long double>& rhs) 
  520. {
  521.     re_ -= _RWSTD_STATIC_CAST(float,rhs.real()); 
  522.     im_ -= _RWSTD_STATIC_CAST(float,rhs.imag()); 
  523.     return *this;
  524. }
  525.  
  526. inline complex<float>&
  527. complex<float>::operator*= (const complex<long double>& rhs) 
  528. {    
  529.     float tmp = re_*_RWSTD_STATIC_CAST(float,rhs.real())-
  530.                 im_*_RWSTD_STATIC_CAST(float,rhs.imag()); 
  531.     im_       = im_*_RWSTD_STATIC_CAST(float,rhs.real())+
  532.                 re_*_RWSTD_STATIC_CAST(float,rhs.imag()); 
  533.     re_       = tmp; 
  534.     return *this;
  535. }
  536. #endif
  537. #endif
  538. #endif /* _RWSTD_NO_MEMBER_TEMPLATES */
  539. //
  540. // complex<double> specializations.
  541. //
  542. inline
  543. complex<double>::complex (const complex<float>& cf)
  544.     : re_(cf.real()), im_(cf.imag()) {}
  545.  
  546. inline 
  547. complex<double>::complex (const complex<double>& cd)
  548.     : re_(cd.real()), im_(cd.imag()) {}
  549.  
  550. #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS 
  551. #ifndef _RWSTD_NO_LONGDOUBLE
  552. inline 
  553. complex<double>::complex (const complex<long double>& cld)
  554.     : re_(_RWSTD_STATIC_CAST(double,cld.real())), 
  555.       im_(_RWSTD_STATIC_CAST(double,cld.imag())) {}
  556. #endif
  557. #endif
  558.  
  559. inline complex<double>&
  560. complex<double>::operator= (double rhs) 
  561. {
  562.     re_ = rhs; im_ = 0.0; return *this;
  563. }
  564.  
  565. inline complex<double>&
  566. complex<double>::operator+= (double rhs) 
  567. {
  568.     re_ += rhs; return *this;
  569. }
  570.  
  571. inline complex<double>&
  572. complex<double>::operator-= (double rhs) 
  573. {
  574.     re_ -= rhs;  return *this;
  575. }
  576.  
  577. inline complex<double>&
  578. complex<double>::operator*= (double rhs) 
  579. {    
  580.     double tmp = re_*rhs; 
  581.     im_       = im_*rhs; 
  582.     re_       = tmp;
  583.     return *this;
  584. }
  585.  
  586.  
  587. #ifdef _RWSTD_NO_MEMBER_TEMPLATES 
  588. inline complex<double>&
  589. complex<double>::operator= (const complex<float>& rhs) 
  590. {
  591.     re_ = rhs.real(); im_ = rhs.imag(); return *this;
  592. }
  593.  
  594. inline complex<double>&
  595. complex<double>::operator+= (const complex<float>& rhs) 
  596. {
  597.     re_ += rhs.real(); im_ += rhs.imag(); return *this;
  598. }
  599.  
  600. inline complex<double>&
  601. complex<double>::operator-= (const complex<float>& rhs) 
  602. {
  603.     re_ -= rhs.real(); im_ -= rhs.imag(); return *this;
  604. }
  605.  
  606. inline complex<double>&
  607. complex<double>::operator*= (const complex<float>& rhs) 
  608. {    
  609.     double tmp = re_*rhs.real()-im_*rhs.imag(); 
  610.     im_        = im_*rhs.real()+re_*rhs.imag(); 
  611.     re_        = tmp;
  612.     return *this;
  613. }
  614.  
  615. inline complex<double>&
  616. complex<double>::operator= (const complex<double>& rhs) 
  617. {
  618.     re_ = rhs.real(); im_ = rhs.imag(); return *this;
  619. }
  620.  
  621. inline complex<double>&
  622. complex<double>::operator+= (const complex<double>& rhs) 
  623. {
  624.     re_ += rhs.real(); im_ += rhs.imag(); return *this;
  625. }
  626.  
  627. inline complex<double>&
  628. complex<double>::operator-= (const complex<double>& rhs) 
  629. {    
  630.     re_ -= rhs.real(); im_ -= rhs.imag(); return *this;
  631. }
  632.  
  633. inline complex<double>& 
  634. complex<double>::operator*= (const complex<double>& rhs) 
  635. {    
  636.     double tmp = re_*rhs.real()-im_*rhs.imag(); 
  637.     im_        = im_*rhs.real()+re_*rhs.imag(); 
  638.     re_        = tmp;
  639.     return *this;
  640. }
  641.  
  642.  
  643. #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS 
  644. #ifndef _RWSTD_NO_LONGDOUBLE
  645. inline complex<double>&
  646. complex<double>::operator= (const complex<long double>& rhs) 
  647. {    
  648.     re_ = _RWSTD_STATIC_CAST(double,rhs.real()); 
  649.     im_ = _RWSTD_STATIC_CAST(double,rhs.imag()); 
  650.     return *this;
  651. }
  652.  
  653. inline complex<double>&
  654. complex<double>::operator+= (const complex<long double>& rhs) 
  655. {    
  656.     re_ += _RWSTD_STATIC_CAST(double,rhs.real()); 
  657.     im_ += _RWSTD_STATIC_CAST(double,rhs.imag()); 
  658.     return *this;
  659. }
  660.  
  661. inline complex<double>& 
  662. complex<double>::operator-= (const complex<long double>& rhs) 
  663. {
  664.     re_ -= _RWSTD_STATIC_CAST(double,rhs.real()); 
  665.     im_ -= _RWSTD_STATIC_CAST(double,rhs.imag()); 
  666.     return *this;
  667. }
  668.  
  669. inline complex<double>& 
  670. complex<double>::operator*= (const complex<long double>& rhs) 
  671. {    
  672.     double tmp = re_*_RWSTD_STATIC_CAST(double,rhs.real())-
  673.                  im_*_RWSTD_STATIC_CAST(double,rhs.imag()); 
  674.     im_        = im_*_RWSTD_STATIC_CAST(double,rhs.real())+
  675.                  re_*_RWSTD_STATIC_CAST(double,rhs.imag()); 
  676.     re_        = tmp; 
  677.     return *this;
  678. }
  679. #endif
  680. #endif
  681. #endif /* _RWSTD_NO_MEMBER_TEMPLATES */
  682.  
  683. //
  684. // complex<long double> specializations.
  685. //
  686.  
  687. #ifndef _RWSTD_NO_LONGDOUBLE
  688. inline 
  689. complex<long double>::complex (const complex<float>& cf)
  690.     : re_(cf.real()), im_(cf.imag()) {}
  691.  
  692. inline 
  693. complex<long double>::complex (const complex<double>& cd)
  694.     : re_(cd.real()), im_(cd.imag()) {}
  695.  
  696. inline 
  697. complex<long double>::complex (const complex<long double>& cld)
  698.     : re_(cld.real()), im_(cld.imag()) {}
  699.  
  700. inline complex<long double>&
  701. complex<long double>::operator+= (long double rhs) 
  702. {
  703.     re_ += rhs; return *this;
  704. }
  705.  
  706. inline complex<long double>&
  707. complex<long double>::operator= (long double rhs) 
  708. {
  709.     re_ = rhs; im_ = 0.0; return *this;
  710. }
  711.  
  712. inline complex<long double>&
  713. complex<long double>::operator-= (long double rhs) 
  714. {
  715.     re_ -= rhs;  return *this;
  716. }
  717.  
  718. inline complex<long double>&
  719. complex<long double>::operator*= (long double rhs) 
  720. {    
  721.     long double tmp = re_*rhs; 
  722.     im_       = im_*rhs; 
  723.     re_       = tmp;
  724.     return *this;
  725. }
  726.  
  727.  
  728. #ifdef _RWSTD_NO_MEMBER_TEMPLATES
  729. inline complex<long double>& 
  730. complex<long double>::operator= (const complex<float>& rhs) 
  731. {
  732.     re_ = rhs.real(); im_ = rhs.imag(); return *this;
  733. }
  734.  
  735. inline complex<long double>& 
  736. complex<long double>::operator+= (const complex<float>& rhs) 
  737. {
  738.     re_ += rhs.real(); im_ += rhs.imag(); return *this;
  739. }
  740.  
  741. inline complex<long double>&
  742. complex<long double>::operator-= (const complex<float>& rhs) 
  743. {
  744.     re_ -= rhs.real(); im_ -= rhs.imag(); return *this;
  745. }
  746.  
  747. inline complex<long double>& 
  748. complex<long double>::operator*= (const complex<float>& rhs) 
  749. {    
  750.     long double tmp = re_*rhs.real()-im_*rhs.imag(); 
  751.     im_             = im_*rhs.real()+re_*rhs.imag(); 
  752.     re_             = tmp;
  753.     return *this;
  754. }
  755.  
  756. inline complex<long double>& 
  757. complex<long double>::operator= (const complex<double>& rhs) 
  758. {
  759.     re_ = rhs.real(); im_ = rhs.imag(); return *this;
  760. }
  761.  
  762. inline complex<long double>& 
  763. complex<long double>::operator+= (const complex<double>& rhs) 
  764. {
  765.     re_ += rhs.real(); im_ += rhs.imag(); return *this;
  766. }
  767.  
  768. inline complex<long double>&
  769. complex<long double>::operator-= (const complex<double>& rhs) 
  770. {    
  771.     re_ -= rhs.real(); im_ -= rhs.imag(); return *this;
  772. }
  773.  
  774. inline complex<long double>& 
  775. complex<long double>::operator*= (const complex<double>& rhs) 
  776. {    
  777.     long double tmp = re_*rhs.real()-im_*rhs.imag(); 
  778.     im_             = im_*rhs.real()+re_*rhs.imag(); 
  779.     re_             = tmp;
  780.     return *this;
  781. }
  782.  
  783. inline complex<long double>&
  784. complex<long double>::operator= (const complex<long double>& rhs) 
  785. {    
  786.     re_ = rhs.real(); im_ = rhs.imag(); return *this;
  787. }
  788.  
  789. inline complex<long double>&
  790. complex<long double>::operator+= (const complex<long double>& rhs) 
  791. {    
  792.     re_ += rhs.real(); im_ += rhs.imag(); return *this;
  793. }
  794.  
  795. inline complex<long double>& 
  796. complex<long double>::operator-= (const complex<long double>& rhs) 
  797. {
  798.     re_ -= rhs.real(); im_ -= rhs.imag(); return *this;
  799. }
  800.  
  801. inline complex<long double>& 
  802. complex<long double>::operator*= (const complex<long double>& rhs) 
  803. {    
  804.     long double tmp = re_*rhs.real()-im_*rhs.imag(); 
  805.     im_             = im_*rhs.real()+re_*rhs.imag(); 
  806.     re_             = tmp; 
  807.     return *this;
  808. }
  809. #endif
  810. #endif /* _RWSTD_NO_MEMBER_TEMPLATES */
  811.  
  812. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  813. template <class T>
  814. template <class X>
  815. complex<T>&
  816. complex<T>::operator/= (const complex<X>& rhs)
  817. {
  818.     T denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  819.     T re    = (re_*rhs.real()+im_*rhs.imag())/denom;
  820.     T im    = (rhs.real()*im_-re_*rhs.imag())/denom;
  821.     re_     = re;
  822.     im_     = im;
  823.     return *this;
  824. }
  825.  
  826. template <class X>
  827. inline complex<float>& 
  828. complex<float>::operator/= (const complex<X>& rhs)  
  829. {
  830.     float denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  831.     float re    = (re_*rhs.real()+im_*rhs.imag())/denom;
  832.     float im    = (rhs.real()*im_-re_*rhs.imag())/denom;
  833.     re_         = re;
  834.     im_         = im;
  835.     return *this;
  836. }
  837.  
  838. template <class X>
  839. inline complex<double>& 
  840. complex<double>::operator/= (const complex<X>& rhs)  
  841. {
  842.     double denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  843.     double re    = (re_*rhs.real()+im_*rhs.imag())/denom;
  844.     double im    = (rhs.real()*im_-re_*rhs.imag())/denom;
  845.     re_         = re;
  846.     im_         = im;
  847.     return *this;
  848. }
  849.  
  850. #ifndef _RWSTD_NO_LONGDOUBLE
  851. template <class X>
  852. inline complex<long double>& 
  853. complex<long double>::operator/= (const complex<X>& rhs)  
  854. {
  855.     long double denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  856.     long double re    = (re_*rhs.real()+im_*rhs.imag())/denom;
  857.     long double im    = (rhs.real()*im_-re_*rhs.imag())/denom;
  858.     re_         = re;
  859.     im_         = im;
  860.     return *this;
  861. }
  862. #endif
  863. #else /* No member function templates, have to specialize :-( */
  864.  
  865. inline complex<float>& 
  866. complex<float>::operator/= (const complex<float>& rhs)  
  867. {
  868.     float denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  869.     float re    = (re_*rhs.real()+im_*rhs.imag())/denom;
  870.     float im    = (rhs.real()*im_-re_*rhs.imag())/denom;
  871.     re_          = re;
  872.     im_          = im;
  873.     return *this;
  874. }
  875.  
  876. #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS
  877. inline complex<float>& 
  878. complex<float>::operator/= (const complex<double>& rhs)  
  879. {
  880.     float denom = _RWSTD_STATIC_CAST(float,rhs.real())*
  881.                   _RWSTD_STATIC_CAST(float,rhs.real()) + 
  882.                   _RWSTD_STATIC_CAST(float,rhs.imag())*
  883.                   _RWSTD_STATIC_CAST(float,rhs.imag());
  884.     float re    = (re_*_RWSTD_STATIC_CAST(float,rhs.real())+
  885.                   im_*_RWSTD_STATIC_CAST(float,rhs.imag()))/denom;
  886.     float im    = (_RWSTD_STATIC_CAST(float,rhs.real())*im_-re_*
  887.                    _RWSTD_STATIC_CAST(float,rhs.imag()))/denom;
  888.     re_          = re;
  889.     im_          = im;
  890.     return *this;
  891. }
  892.  
  893. #ifndef _RWSTD_NO_LONGDOUBLE
  894. inline complex<float>& 
  895. complex<float>::operator/= (const complex<long double>& rhs)  
  896. {
  897.     float denom = _RWSTD_STATIC_CAST(float,rhs.real())*
  898.                   _RWSTD_STATIC_CAST(float,rhs.real()) + 
  899.                   _RWSTD_STATIC_CAST(float,rhs.imag())*
  900.                   _RWSTD_STATIC_CAST(float,rhs.imag());
  901.     float re    = (re_*_RWSTD_STATIC_CAST(float,rhs.real())+
  902.                   im_*_RWSTD_STATIC_CAST(float,rhs.imag()))/denom;
  903.     float im    = (_RWSTD_STATIC_CAST(float,rhs.real())*im_-
  904.                    re_*_RWSTD_STATIC_CAST(float,rhs.imag()))/denom;
  905.     re_          = re;
  906.     im_          = im;
  907.     return *this;
  908. }
  909. #endif 
  910. #endif
  911.  
  912. inline complex<double>& 
  913. complex<double>::operator/= (const complex<float>& rhs)  
  914. {
  915.     double denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  916.     double re    = (re_*rhs.real()+im_*rhs.imag())/denom;
  917.     double im    = (rhs.real()*im_-re_*rhs.imag())/denom;
  918.     re_               = re;
  919.     im_               = im;
  920.     return *this;
  921. }
  922.  
  923. inline complex<double>&
  924. complex<double>::operator/= (const complex<double>& rhs)
  925. {
  926.     double denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  927.     double re    = (re_*rhs.real()+im_*rhs.imag())/denom;
  928.     double im    = (rhs.real()*im_-re_*rhs.imag())/denom;
  929.     re_               = re;
  930.     im_               = im;
  931.     return *this;
  932. }
  933.  
  934. #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS
  935. #ifndef _RWSTD_NO_LONGDOUBLE
  936. inline complex<double>& 
  937. complex<double>::operator/= (const complex<long double>& rhs)  
  938. {
  939.     double denom = _RWSTD_STATIC_CAST(double,rhs.real())*
  940.                   _RWSTD_STATIC_CAST(double,rhs.real()) + 
  941.                   _RWSTD_STATIC_CAST(double,rhs.imag())*
  942.                   _RWSTD_STATIC_CAST(double,rhs.imag());
  943.     double re    = (re_*_RWSTD_STATIC_CAST(double,rhs.real())+
  944.                   im_*_RWSTD_STATIC_CAST(double,rhs.imag()))/denom;
  945.     double im    = (_RWSTD_STATIC_CAST(double,rhs.real())*im_-
  946.                    re_*_RWSTD_STATIC_CAST(double,rhs.imag()))/denom;
  947.     re_          = re;
  948.     im_          = im;
  949.     return *this;
  950. }
  951. #endif
  952. #endif
  953.  
  954. #ifndef _RWSTD_NO_LONGDOUBLE
  955. inline complex<long double>& 
  956. complex<long double>::operator/= (const complex<float>& rhs)  
  957. {
  958.     long double denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  959.     long double re    = (re_*rhs.real()+im_*rhs.imag())/denom;
  960.     long double im    = (rhs.real()*im_-re_*rhs.imag())/denom;
  961.     re_               = re;
  962.     im_               = im;
  963.     return *this;
  964. }
  965.  
  966. inline complex<long double>& 
  967. complex<long double>::operator/= (const complex<double>& rhs)  
  968. {
  969.     long double denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  970.     long double re    = (re_*rhs.real()+im_*rhs.imag())/denom;
  971.     long double im    = (rhs.real()*im_-re_*rhs.imag())/denom;
  972.     re_               = re;
  973.     im_               = im;
  974.     return *this;
  975. }
  976.  
  977. inline complex<long double>& 
  978. complex<long double>::operator/= (const complex<long double>& rhs)  
  979. {
  980.     long double denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  981.     long double re    = (re_*rhs.real()+im_*rhs.imag())/denom;
  982.     long double im    = (rhs.real()*im_-re_*rhs.imag())/denom;
  983.     re_               = re;
  984.     im_               = im;
  985.     return *this;
  986. }
  987. #endif
  988. #endif
  989.  
  990. inline complex<float>& 
  991. complex<float>::operator/= (float rhs)  
  992. {
  993.     float denom = rhs*rhs;
  994.     float re    = (re_*rhs)/denom;
  995.     float im    = (rhs*im_)/denom;
  996.     re_               = re;
  997.     im_               = im;
  998.     return *this;
  999. }
  1000.  
  1001. inline complex<double>& 
  1002. complex<double>::operator/= (double rhs)  
  1003. {
  1004.     double denom = rhs*rhs;
  1005.     double re    = (re_*rhs)/denom;
  1006.     double im    = (rhs*im_)/denom;
  1007.     re_               = re;
  1008.     im_               = im;
  1009.     return *this;
  1010. }
  1011.  
  1012.  
  1013. #ifndef _RWSTD_NO_LONGDOUBLE
  1014. inline complex<long double>& 
  1015. complex<long double>::operator/= (long double rhs)  
  1016. {
  1017.     long double denom = rhs*rhs;
  1018.     long double re    = (re_*rhs)/denom;
  1019.     long double im    = (rhs*im_)/denom;
  1020.     re_               = re;
  1021.     im_               = im;
  1022.     return *this;
  1023. }
  1024. #endif
  1025.  
  1026.  
  1027. //
  1028. // complex non-member operations
  1029. //
  1030.  
  1031. template <class T>
  1032. inline complex<T> operator+ (const complex<T>& lhs, const complex<T>& rhs)
  1033. {
  1034.     complex<T> tmp = lhs; return tmp += rhs;
  1035. }
  1036.  
  1037. template <class T>
  1038. inline complex<T> operator+ (const complex<T>& lhs, const T& rhs)
  1039. {
  1040.     return complex<T>(rhs+lhs.real(), lhs.imag());
  1041. }
  1042.  
  1043. template <class T>
  1044. inline complex<T> operator+ (const T& lhs, const complex<T>& rhs)
  1045. {
  1046.     return complex<T>(lhs+rhs.real(), rhs.imag());
  1047. }
  1048.  
  1049. template <class T>
  1050. inline complex<T> operator- (const complex<T>& lhs, const complex<T>& rhs)
  1051. {
  1052.     complex<T> tmp = lhs; return tmp -= rhs;
  1053. }
  1054.  
  1055. template <class T>
  1056. inline complex<T> operator- (const complex<T>& lhs, const T& rhs)
  1057. {
  1058.     return complex<T>(lhs.real()-rhs, lhs.imag());
  1059. }
  1060.  
  1061. template <class T>
  1062. inline complex<T> operator- (const T& lhs, const complex<T>& rhs)
  1063. {
  1064.     return complex<T>(lhs-rhs.real(), -rhs.imag());
  1065. }
  1066.  
  1067. template <class T>
  1068. inline complex<T> operator* (const complex<T>& lhs, const complex<T>& rhs)
  1069. {
  1070.     complex<T> tmp = lhs; return tmp *= rhs;
  1071. }
  1072.  
  1073. template <class T>
  1074. inline complex<T> operator* (const complex<T>& lhs, const T& rhs)
  1075. {
  1076.     return complex<T>(rhs*lhs.real(), rhs*lhs.imag());
  1077. }
  1078.  
  1079. template <class T>
  1080. inline complex<T> operator* (const T& lhs, const complex<T>& rhs)
  1081. {
  1082.     return complex<T>(lhs*rhs.real(), lhs*rhs.imag());
  1083. }
  1084.  
  1085. template <class T>
  1086. inline complex<T> operator/ (const complex<T>& lhs, const complex<T>& rhs)
  1087. {
  1088.     complex<T> tmp = lhs; return tmp /= rhs;
  1089. }
  1090.  
  1091. template <class T>
  1092. inline complex<T> operator/ (const complex<T>& lhs, const T& rhs)
  1093. {
  1094.     return complex<T>(lhs.real()/rhs, lhs.imag()/rhs);
  1095. }
  1096.  
  1097. template <class T>
  1098. inline complex<T> operator/ (const T& lhs, const complex<T>& rhs)
  1099. {
  1100.     register T denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  1101.     return complex<T>(lhs*rhs.real()/denom,(-lhs*rhs.imag())/denom);
  1102. }
  1103.  
  1104. template <class T>
  1105. inline complex<T> operator+ (const complex<T>& lhs) { return lhs; }
  1106.  
  1107. template <class T>
  1108. inline complex<T> operator- (const complex<T>& lhs)
  1109. {
  1110.     return complex<T>(-lhs.real(), -lhs.imag());
  1111.  
  1112. template <class T>
  1113. inline bool operator== (const complex<T>& lhs, const complex<T>& rhs)
  1114. {
  1115.     return lhs.real() == rhs.real() && lhs.imag() == rhs.imag();
  1116.  
  1117. template <class T>
  1118. inline bool operator== (const T& lhs, const complex<T>& rhs)
  1119. {
  1120.     return lhs == rhs.real() && rhs.imag() == 0;
  1121.  
  1122. template <class T>
  1123. inline bool operator== (const complex<T>& lhs, const T& rhs)
  1124. {
  1125.     return lhs.real() == rhs && lhs.imag() == 0;
  1126.  
  1127. #ifndef _RWSTD_NO_NAMESPACE
  1128. template <class T>
  1129. inline bool operator!= (const complex<T>& lhs, const complex<T>& rhs)
  1130. {
  1131.     return lhs.real() != rhs.real() || lhs.imag() != rhs.imag();
  1132. #endif
  1133.  
  1134. template <class T>
  1135. inline bool operator!= (const T& lhs, const complex<T>& rhs)
  1136. {
  1137.     return lhs != rhs.real() || rhs.imag() != 0;
  1138.  
  1139. template <class T>
  1140. inline bool operator!= (const complex<T>& lhs, const T& rhs)
  1141. {
  1142.     return lhs.real() != rhs || lhs.imag() != 0;
  1143.  
  1144. //
  1145. // complex value operations
  1146. //
  1147.  
  1148. // Cope with namespace problems
  1149. #if defined(_RWSTD_NO_NEW_HEADER) && !defined(_RWSTD_NO_NAMESPACE) 
  1150. #define _RWSTD_C_SCOPE_SIN ::sin
  1151. #define _RWSTD_C_SCOPE_SINH ::sinh
  1152. #define _RWSTD_C_SCOPE_COS ::cos
  1153. #define _RWSTD_C_SCOPE_COSH ::cosh
  1154. #define _RWSTD_C_SCOPE_ATAN2 ::atan2
  1155. #define _RWSTD_C_SCOPE_ATAN ::atan
  1156. #define _RWSTD_C_SCOPE_EXP ::exp
  1157. #define _RWSTD_C_SCOPE_POW ::pow
  1158. #define _RWSTD_C_SCOPE_SQRT ::sqrt
  1159. #define _RWSTD_C_SCOPE_LOG ::log
  1160. #define _RWSTD_C_SCOPE_LOG10 ::log10
  1161. #else
  1162. #define _RWSTD_C_SCOPE_SIN sin
  1163. #define _RWSTD_C_SCOPE_SINH sinh
  1164. #define _RWSTD_C_SCOPE_COS cos
  1165. #define _RWSTD_C_SCOPE_COSH cosh
  1166. #define _RWSTD_C_SCOPE_ATAN2 atan2
  1167. #define _RWSTD_C_SCOPE_ATAN atan
  1168. #define _RWSTD_C_SCOPE_EXP exp
  1169. #define _RWSTD_C_SCOPE_POW pow
  1170. #define _RWSTD_C_SCOPE_SQRT sqrt
  1171. #define _RWSTD_C_SCOPE_LOG log
  1172. #define _RWSTD_C_SCOPE_LOG10 log10
  1173. #endif
  1174.  
  1175. template<class T>
  1176. inline T real (const complex<T>& a) { return a.real(); }
  1177.  
  1178. template<class T>
  1179. inline T imag (const complex<T>& a) { return a.imag(); }
  1180.  
  1181. template <class T>
  1182. inline T norm (const complex<T>& a)
  1183. {
  1184.     return a.real()*a.real() + a.imag()*a.imag();
  1185. }
  1186.  
  1187. template <class T>
  1188. inline T abs (const complex<T>& a) { return (_RWSTD_C_SCOPE_SQRT(norm(a))); }
  1189.  
  1190. //
  1191. // We guarantee that arg(complex<T>(0,0)) == 0.
  1192. //
  1193.  
  1194. template <class T>
  1195. inline T arg (const complex<T>& a)
  1196. {
  1197.     return a == complex<T>(0,0) ? T(0) : _RWSTD_C_SCOPE_ATAN2(a.imag(), a.real());
  1198. }
  1199.  
  1200. template <class T>
  1201. complex<T> conj (const complex<T>& a)
  1202. {
  1203.     return complex<T>(a.real(), -a.imag());
  1204. }
  1205.  
  1206. #if defined(_MSC_VER) &&  _MSC_VER < 901
  1207. //
  1208. // A very bizarre Microsoft problem.
  1209. //
  1210. _RWSTD_TEMPLATE 
  1211. inline complex<float> conj (const complex<float>& a)
  1212. {
  1213.     return complex<float>(a.real(), -a.imag());
  1214. }
  1215. _RWSTD_TEMPLATE 
  1216. inline complex<double> conj (const complex<double>& a)
  1217. {
  1218.     return complex<double>(a.real(), -a.imag());
  1219. }
  1220.  
  1221. #ifndef _RWSTD_NO_LONGDOUBLE
  1222. _RWSTD_TEMPLATE 
  1223. inline complex<long double> conj (const complex<long double>& a)
  1224. {
  1225.     return complex<long double>(a.real(), -a.imag());
  1226. }
  1227. #endif
  1228. #endif
  1229.  
  1230. template <class T>
  1231. #ifndef _RWSTD_NO_INIT_CONST_TEMPLATE_REF_ARG
  1232. inline complex<T> polar (const T& r, const T& theta = 0)
  1233. #else
  1234. inline complex<T> polar (const T& r, const T& theta)
  1235. #endif
  1236. {
  1237.     return complex<T>(r*_RWSTD_C_SCOPE_COS(theta), r*_RWSTD_C_SCOPE_SIN(theta));
  1238. }
  1239.  
  1240. //
  1241. // transcendentals
  1242. //
  1243.  
  1244. //
  1245. // complex<T> cosine of complex<T> number a
  1246. //    cos (a) = cos u * cosh v - i * sin u * sinh v
  1247. //
  1248.  
  1249. template <class T>
  1250. inline complex<T> cos (const complex<T>& a)
  1251. {
  1252.     return complex<T>(_RWSTD_C_SCOPE_COS(a.real())*_RWSTD_C_SCOPE_COSH(a.imag()),
  1253.                       -_RWSTD_C_SCOPE_SIN(a.real())*_RWSTD_C_SCOPE_SINH(a.imag()));
  1254. }
  1255.  
  1256. //
  1257. // complex<T> hyperbolic cosine of complex<T> number a
  1258. //    cosh (a) = cosh u * cosv + i * sinh u * sin v
  1259. //
  1260.  
  1261. template <class T>
  1262. inline complex<T> cosh (const complex<T>& a)
  1263. {
  1264.     return complex<T>(_RWSTD_C_SCOPE_COSH(a.real())*_RWSTD_C_SCOPE_COS(a.imag()),
  1265.                       _RWSTD_C_SCOPE_SINH(a.real())*_RWSTD_C_SCOPE_SIN(a.imag()));
  1266. }
  1267.  
  1268. //
  1269. // complex<T> exponential of  complex<T> number a
  1270. //    exp (a) = exp(u) * (cos v + i * sin v)
  1271. //
  1272.  
  1273. template <class T>
  1274. inline complex<T> exp (const complex<T>& a)
  1275. {
  1276.     register T e = _RWSTD_C_SCOPE_EXP(a.real());
  1277.     return complex<T>(e*_RWSTD_C_SCOPE_COS(a.imag()), e*_RWSTD_C_SCOPE_SIN(a.imag()));
  1278. }
  1279.  
  1280. //
  1281. // complex<T> natural log of complex<T> number a
  1282. //    log(a) = log(r) + i * theta
  1283. //
  1284.  
  1285. template <class T>
  1286. inline complex<T> log (const complex<T>& a)
  1287. {
  1288.     return complex<T>(_RWSTD_C_SCOPE_LOG(abs(a)), arg(a));
  1289. }
  1290.  
  1291. template <class T>
  1292. complex<T> log10 (const complex<T>& a);
  1293.  
  1294. //
  1295. // For all the power functions:
  1296. //
  1297. //   0**0 == 1
  1298. //   0**x == 0 for x != 0
  1299. //
  1300.  
  1301. //
  1302. // complex<T> number a raised to an integer power n
  1303. //
  1304. // a**n = r**n * (cos(n theta) + i sin (n theta))
  1305. //
  1306.  
  1307. template <class T>
  1308. inline complex<T> pow (const complex<T>& a, int n)
  1309. {
  1310.     if (a == complex<T>(0,0))
  1311.     {
  1312.         if (n == 0) 
  1313.           return complex<T>(1,0);
  1314.         else
  1315.           return complex<T>(0,0);
  1316.     }
  1317.  
  1318.     if (a.imag() == 0)
  1319.     {
  1320.        if (a.real() < 0)
  1321.           return pow(a, complex<T>(n,0));
  1322.        else
  1323. #ifndef _RWSTD_NO_OVERLOAD_C_POW
  1324.           return complex<T>(_RWSTD_C_SCOPE_POW(a.real(),T(n)), 0);
  1325. #else
  1326.           return complex<T>(_RWSTD_C_SCOPE_POW(double(a.real()),double(n)), 0);
  1327. #endif /* _RWSTD_NO_OVERLOAD_C_POW */
  1328.     }
  1329.  
  1330. #ifndef _RWSTD_NO_OVERLOAD_C_POW
  1331.     register T r  = _RWSTD_C_SCOPE_POW(T(abs(a)), T(n));
  1332. #else
  1333.     register T r  = _RWSTD_C_SCOPE_POW(double(abs(a)), double(n));
  1334. #endif
  1335.  
  1336.     register T th = T(n) * arg(a);
  1337.  
  1338.     return complex<T>(r*_RWSTD_C_SCOPE_COS(th), r*_RWSTD_C_SCOPE_SIN(th));
  1339. }
  1340.  
  1341.  
  1342. //
  1343. // complex<T> number a raised to a real power s
  1344. //
  1345. // a**s = exp(s * log(a))
  1346. //
  1347.  
  1348. template <class T>
  1349. inline complex<T> pow (const complex<T>& a, T s)
  1350. {
  1351.     if (a == complex<T>(0,0))
  1352.     {
  1353.         if (s == T(0))
  1354.            return complex<T>(1,0);
  1355.         else
  1356.            return complex<T>(0,0);
  1357.     }
  1358.     if (a.imag() == 0)
  1359.     {
  1360.        if (a.real() < 0)
  1361.           return pow(a, complex<T>(s,0));
  1362.        else
  1363. #ifndef _RWSTD_NO_OVERLOAD_C_POW
  1364.           return complex<T>(_RWSTD_C_SCOPE_POW(a.real(),s), 0);
  1365. #else
  1366.           return complex<T>(_RWSTD_C_SCOPE_POW(double(a.real()),double(s)), 0);
  1367. #endif /* _RWSTD_NO_OVERLOAD_C_POW */
  1368.     }
  1369.     return exp(s*log(a));
  1370. }   
  1371.  
  1372.  
  1373. //
  1374. // real number s raised to a complex<T> power a
  1375. //
  1376. //  s**a = exp(a * log (s))
  1377. //
  1378.  
  1379. template <class T>
  1380. inline complex<T> pow (T s, const complex<T>& a)
  1381. {
  1382.     if (s == T(0))
  1383.     {
  1384.         if (a == complex<T>(0,0)) 
  1385.            return complex<T>(1,0);
  1386.         else
  1387.            return complex<T>(0,0);
  1388.     }
  1389.     if (s < 0)
  1390.         return pow(complex<T>(s,0), a);
  1391.  
  1392.     if (a.imag() == 0)
  1393. #ifndef _RWSTD_NO_OVERLOAD_C_POW
  1394.         return complex<T>(_RWSTD_C_SCOPE_POW(s, a.real()), 0);
  1395. #else
  1396.         return complex<T>(_RWSTD_C_SCOPE_POW(double(s), double(a.real())), 0);
  1397. #endif /* _RWSTD_NO_OVERLOAD_C_POW */
  1398.  
  1399.     return complex<T>(exp(a * (T) _RWSTD_C_SCOPE_LOG(s)));
  1400. }
  1401.  
  1402.  
  1403. //
  1404. // complex<T> number a1 raised to a complex<T> power a2
  1405. //
  1406. // a1**a2 = rho * (cos(phi) + i sin(phi))
  1407. //      rho = r1 **u2   *  exp (-v2* theta1)
  1408. //    phi = v2 * log(r1) + u2 * theta1
  1409. //
  1410.  
  1411. template <class T>
  1412. inline complex<T> pow (const complex<T>& a1, const complex<T>& a2)
  1413. {
  1414.     if (a1 == complex<T>(0,0))
  1415.     {
  1416.         if (a2 == complex<T>(0,0))
  1417.            return complex<T>(1,0);
  1418.         else
  1419.            return complex<T>(0,0);
  1420.     }
  1421.  
  1422.     T r1   = abs(a1);
  1423.     T u2   = real(a2);
  1424.     T v2   = imag(a2);
  1425.     T th1  = arg(a1);
  1426. #ifndef _RWSTD_NO_OVERLOAD_C_POW
  1427.     T rho  = _RWSTD_C_SCOPE_POW(r1, u2) * _RWSTD_C_SCOPE_EXP(-v2 *th1);
  1428. #else
  1429.     T rho  = _RWSTD_C_SCOPE_POW(double(r1), double(u2)) * _RWSTD_C_SCOPE_EXP(-v2 *th1);
  1430. #endif /* _RWSTD_NO_OVERLOAD_C_POW */
  1431.     T phi  = v2 * _RWSTD_C_SCOPE_LOG(r1) + u2 * th1;
  1432.  
  1433.     return complex<T>(rho*_RWSTD_C_SCOPE_COS(phi), rho*_RWSTD_C_SCOPE_SIN(phi));
  1434. }     
  1435.  
  1436.  
  1437. //
  1438. // complex<T> sine of complex<T> number a
  1439. //    sin (a) = sin u * cosh v + i * cos u * sinh v
  1440. //
  1441. template <class T>
  1442. inline complex<T> sin (const complex<T>& a)
  1443. {
  1444.     return complex<T>(_RWSTD_C_SCOPE_SIN(a.real())*_RWSTD_C_SCOPE_COSH(a.imag()),
  1445.                       _RWSTD_C_SCOPE_COS(a.real())*_RWSTD_C_SCOPE_SINH(a.imag()));
  1446. }
  1447.  
  1448. //
  1449. // complex<T> hyperbolic sine of complex<T> number a
  1450. //    sinh (a) = sinh u cos v + i cosh u sin v
  1451. //
  1452. template <class T>
  1453. inline complex<T> sinh (const complex<T>& a)
  1454. {
  1455.     return complex<T>(_RWSTD_C_SCOPE_SINH(a.real())*_RWSTD_C_SCOPE_COS(a.imag()),
  1456.                       _RWSTD_C_SCOPE_COSH(a.real())*_RWSTD_C_SCOPE_SIN(a.imag()));
  1457. }
  1458.  
  1459. //
  1460. // complex<T> square root of complex<T> number a
  1461. //      sqrt(a) = sqrt(r) * ( cos (theta/2) + i sin (theta/2) )
  1462. //
  1463. template <class T>
  1464. inline complex<T> sqrt (const complex<T>& a)
  1465. {
  1466.     register T r  = _RWSTD_C_SCOPE_SQRT(abs(a));
  1467.     register T th = arg(a)/2.;
  1468.     return complex<T>(r*_RWSTD_C_SCOPE_COS(th), r*_RWSTD_C_SCOPE_SIN(th));
  1469. }
  1470.  
  1471. template <class T>
  1472. inline complex<T> tan (const complex<T>& a) { return sin(a)/cos(a); }
  1473.  
  1474. template <class T>
  1475. inline complex<T> tanh (const complex<T>& a) { return sinh(a)/cosh(a);
  1476. }
  1477.  
  1478.  
  1479. #ifdef _RW_STD_IOSTREAM
  1480.  
  1481. template <class T,class charT, class traits>
  1482. basic_istream<charT, traits >& _RWSTDExportTemplate 
  1483. operator>> (basic_istream<charT, traits >& is,complex<T>& x);
  1484. template <class T,class charT,class traits>
  1485.  
  1486. basic_ostream<charT,traits >& _RWSTDExportTemplate 
  1487. operator<< (basic_ostream<charT, traits >& os,const complex<T>& x);
  1488.  
  1489. #else
  1490.  
  1491. template <class T>
  1492. istream& _RWSTDExportTemplate operator>> (istream& is, complex<T>& x);
  1493. template <class T>
  1494. ostream& _RWSTDExportTemplate operator<< (ostream& os, const complex<T>& x);
  1495.  
  1496. #endif
  1497.  
  1498. #ifndef _RWSTD_NO_NAMESPACE
  1499. }
  1500. #endif
  1501.  
  1502. #if defined(_RWSTD_NO_DESTROY_BUILTIN) || defined(_RWSTD_NO_DESTROY_NONBUILTIN)
  1503.  
  1504. #ifndef _RWSTD_NO_NAMESPACE
  1505. namespace __rogue_wave_std {
  1506. #endif
  1507. //
  1508. // Specializations of STL destroy for complex.
  1509. //
  1510. inline void __destroy (complex<float>**)         {}
  1511. inline void __destroy (complex<float>***)        {}
  1512. inline void __destroy (complex<float>****)       {}
  1513. inline void __destroy (complex<double>**)        {}
  1514. inline void __destroy (complex<double>***)       {}
  1515. inline void __destroy (complex<double>****)      {}
  1516. #ifndef _RWSTD_NO_LONGDOUBLE
  1517. inline void __destroy (complex<long double>**)   {}
  1518. inline void __destroy (complex<long double>***)  {}
  1519. inline void __destroy (complex<long double>****) {}
  1520. #endif
  1521.  
  1522. #ifndef _RWSTD_NO_NAMESPACE
  1523. }
  1524. #endif
  1525. #endif
  1526.  
  1527. #ifdef _RWSTD_NO_TEMPLATE_REPOSITORY
  1528. #include <complex.cc>
  1529. #endif
  1530.  
  1531. #pragma option pop
  1532. #endif /* __STD_COMPLEX */
  1533.